#pragma once

#include <Arduino.h>
#include <map>

#define MOTOR_NUM 4
#define IO_NUM 8

#define PWM_RESOLUTION 1000  // PWM分辨率
#define PWM_FREQUENCY  13    // PWM频率

#define ESP32_LED 2
#define A1 17
#define A2 24

#define MOTOR_MOVE_STOP    0  // 电机停止
#define MOTOR_MOVE_FORWARD 1  // 电机正转
#define MOTOR_MOVE_REVERSE 2  // 电机反转

#define MOTOR_A 0  // 电机A - 前轮左
#define MOTOR_B 1  // 电机B - 前轮右
#define MOTOR_C 2  // 电机C - 后轮左
#define MOTOR_D 3  // 电机D - 后轮右

enum emChannelNum {
    emChannel_0 = 0,
    emChannel_1 = 1,
    emChannel_2 = 2,
    emChannel_3 = 3,
    emChannel_4 = 4,
    emChannel_5 = 5,
    emChannel_6 = 6,
    emChannel_7 = 7,

    emChannel_NULL,
};

enum emIONum {
    emIO_A1 = 17,
    emIO_A2 = 24,
    emIO_B1 = 2,
    emIO_B2 = 3,
    emIO_C1 = 4,
    emIO_C2 = 5,
    emIO_D1 = 6,
    emIO_D2 = 7,
};

typedef struct motor {
    struct channelandIO {
        emChannelNum channel;
        emIONum      IO;
    };

    channelandIO pin_1;
    channelandIO pin_2;
} stMOTOR, *lpstMOTOR;

class Car
{
public:
    Car(/* args */);
    ~Car();

    void initMotor();

    void pinOutput(const emChannelNum channel, const uint8_t output, const uint8_t speed = 0);
    void motorRun(const uint8_t motorID, const float motorSpeed, const uint8_t motorDirection);
    void moveCar(uint8_t xAxis, uint8_t yAxis);

private:
    stMOTOR m_motor[MOTOR_NUM];  // 4个电机的信息

    uint32_t getDutyBySpeed(uint8_t speed);
    bool     isChannel(const emChannelNum channel);
    void     setMotorPin(stMOTOR& motor, emIONum pin1_IO, emChannelNum pin1_C, emIONum pin2_IO, emChannelNum pin2_C);

};  // Car 小车类
